package com.ruoqing.gateway.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoqing.gateway.dao.GateWayDao;
import com.ruoqing.gateway.domain.GateWayDbEntity;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
	* @author YaoXian
	* @title: GateWayService
	* @projectName ruoxi-blog
	* @description: GateWay网关整合数据库实现动态网关
	* @date 2020-11-09 23:46
	*/
@Service
public class GateWayService implements ApplicationEventPublisherAware {
		
		private ApplicationEventPublisher publisher;
		@Resource
		private GateWayDao gateWayDao;
		
		@Resource
		private RouteDefinitionWriter routeDefinitionWriter;
		
		@Override
		public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
				this.publisher = applicationEventPublisher;
		}
		
		public void initAllRoute() {
				QueryWrapper<GateWayDbEntity> queryWrapper = new QueryWrapper<GateWayDbEntity>();
				// 从数据库查询配置的网关配置
				List<GateWayDbEntity> gateWayDbEntityList = gateWayDao.selectList(queryWrapper);
				for (GateWayDbEntity gw :
								gateWayDbEntityList) {
						loadRoute(gw);
				}
		}
		
		public String loadRoute(GateWayDbEntity gateWayEntity) {
				RouteDefinition definition = new RouteDefinition();
				Map<String, String> predicateParams = new HashMap<String, String>(8);
				PredicateDefinition predicate = new PredicateDefinition();
				FilterDefinition filterDefinition = new FilterDefinition();
				Map<String, String> filterParams = new HashMap<String,String>(8);
				// 如果配置路由type为0的话 则从注册中心获取服务
				URI uri;
				if (gateWayEntity.getRouteType().equals("0")) {
					uri = UriComponentsBuilder.fromUriString("lb://" + gateWayEntity.getRouteUrl() + "/").build().toUri();
				} else {
						uri = UriComponentsBuilder.fromHttpUrl(gateWayEntity.getRouteUrl()).build().toUri();
				}
				// 定义的路由唯一的id
				definition.setId(gateWayEntity.getRouteId());
				predicate.setName("Path");
				//路由转发地址
				predicateParams.put("pattern", gateWayEntity.getRoutePattern());
				predicate.setArgs(predicateParams);
				
				// 名称是固定的, 路径去前缀
				filterDefinition.setName("StripPrefix");
				filterParams.put("_genkey_0", "1");
				filterDefinition.setArgs(filterParams);
				definition.setPredicates(Arrays.asList(predicate));
				definition.setFilters(Arrays.asList(filterDefinition));
				definition.setUri(uri);
				routeDefinitionWriter.save(Mono.just(definition)).subscribe();
				this.publisher.publishEvent(new RefreshRoutesEvent(this));
				return "success";
		}
}
